package org.koin.test.mock;

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class MockProviderRule implements TestRule {

    private Provider mockProvider;

    public MockProviderRule() {
    }

    public MockProviderRule(Provider mockProvider) {
        this.mockProvider = mockProvider;
    }

    public static MockProviderRule create(Provider mockProvider) {
        return new MockProviderRule(mockProvider);
    }

    @Override
    public Statement apply(Statement base, Description description) {
        class Statement extends org.junit.runners.model.Statement {
            private volatile Statement INSTANCE;

            private Statement() {

            }

            public Statement INSTANCE() {
                if (INSTANCE == null) {
                    synchronized (Statement.class) {
                        if (INSTANCE == null) {
                            INSTANCE = new Statement();
                        }
                    }
                }
                return INSTANCE;
            }

            @Override
            public void evaluate() throws Throwable {
                MockProvider.INSTANCE().register(mockProvider);
            }
        }

        return new Statement().INSTANCE();
    }
}
